#include "SCcalculator.h"
#include "ui_SCcalculator.h"



string text;
string g_strText;

vector<string> calcu;
string history;

SCcalculator::SCcalculator(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SCcalculator)
{
    ui->setupUi(this);

    Factory::RegisterClass<Hash> reg_Hash("#");

    REGISTRAR(Plus,"+")
    REGISTRAR(Minus,"-")
    REGISTRAR(Multiply,"*")
    REGISTRAR(Divide,"/")
    REGISTRAR(Equal,"=")
    REGISTRAR(Pow,"^")
    REGISTRAR(Mod,"%")
    REGISTRAR(Sin,"sin")
    REGISTRAR(Tan,"tan")
    REGISTRAR(Cos,"cos")
    REGISTRAR(Sqrt,"sqrt")
    REGISTRAR(Log,"log")
    REGISTRAR(Ln,"ln")
    REGISTRAR(Reciprocal,"rec")
    REGISTRAR(Factorial,"fact")
    REGISTRAR(Nagative,"~")
    REGISTRAR(Left,"(")
    REGISTRAR(Right,")")
    REGISTRAR(Square, "x^2")
    REGISTRAR(Abs, "|x|")
    REGISTRAR(Exp, "exp(x)")

    //连接信号和槽
    connect(ui->m_0,&QPushButton::clicked,this,&SCcalculator::button_0);
    connect(ui->m_1,&QPushButton::clicked,this,&SCcalculator::button_1);
    connect(ui->m_2,&QPushButton::clicked,this,&SCcalculator::button_2);
    connect(ui->m_3,&QPushButton::clicked,this,&SCcalculator::button_3);
    connect(ui->m_4,&QPushButton::clicked,this,&SCcalculator::button_4);
    connect(ui->m_5,&QPushButton::clicked,this,&SCcalculator::button_5);
    connect(ui->m_6,&QPushButton::clicked,this,&SCcalculator::button_6);
    connect(ui->m_7,&QPushButton::clicked,this,&SCcalculator::button_7);
    connect(ui->m_8,&QPushButton::clicked,this,&SCcalculator::button_8);
    connect(ui->m_9,&QPushButton::clicked,this,&SCcalculator::button_9);
    connect(ui->m_pi,&QPushButton::clicked,this,&SCcalculator::button_pi);

    connect(ui->m_e,&QPushButton::clicked,this,&SCcalculator::button_e);
    connect(ui->m_dot,&QPushButton::clicked,this,&SCcalculator::button_dot);
    connect(ui->m_plus,&QPushButton::clicked,this,&SCcalculator::button_plus);
    connect(ui->m_minus,&QPushButton::clicked,this,&SCcalculator::button_minus);
    connect(ui->m_multiply,&QPushButton::clicked,this,&SCcalculator::button_multiply);
    connect(ui->m_divide,&QPushButton::clicked,this,&SCcalculator::button_divide);
    connect(ui->m_pow,&QPushButton::clicked,this,&SCcalculator::button_pow);
    connect(ui->m_mod,&QPushButton::clicked,this,&SCcalculator::button_mod);
    connect(ui->m_sin,&QPushButton::clicked,this,&SCcalculator::button_sin);
    connect(ui->m_cos,&QPushButton::clicked,this,&SCcalculator::button_cos);
    connect(ui->m_tan,&QPushButton::clicked,this,&SCcalculator::button_tan);
    connect(ui->m_sqrt,&QPushButton::clicked,this,&SCcalculator::button_sqrt);
    connect(ui->m_log,&QPushButton::clicked,this,&SCcalculator::button_log);
    connect(ui->m_ln,&QPushButton::clicked,this,&SCcalculator::button_ln);

    connect(ui->m_reciprocal,&QPushButton::clicked,this,&SCcalculator::button_reciprocal);
    connect(ui->m_factorial,&QPushButton::clicked,this,&SCcalculator::button_factorial);
    connect(ui->m_negative,&QPushButton::clicked,this,&SCcalculator::button_nagative);
    connect(ui->m_equal,&QPushButton::clicked,this,&SCcalculator::button_equal);
    // 创建一个 QShortcut，将回车键（Enter）设为快捷键，并将其与 m_equal 按钮的点击事件关联
    QShortcut* shortcutEnter = new QShortcut(QKeySequence(Qt::Key_Return), this);
    connect(shortcutEnter, &QShortcut::activated, ui->m_equal, &QPushButton::click);

    // 小键盘上的 Enter 也能触发，添加一个 QShortcut
    QShortcut* shortcutNumpadEnter = new QShortcut(QKeySequence(Qt::Key_Enter), this);
    connect(shortcutNumpadEnter, &QShortcut::activated, ui->m_equal, &QPushButton::click);

    connect(ui->m_left,&QPushButton::clicked,this,&SCcalculator::button_left);
    connect(ui->m_right,&QPushButton::clicked,this,&SCcalculator::button_right);
    connect(ui->m_clear,&QPushButton::clicked,this,&SCcalculator::button_clear);
    connect(ui->m_clearnum,&QPushButton::clicked,this,&SCcalculator::button_clearnum);
    connect(ui->m_delete,&QPushButton::clicked,this,&SCcalculator::button_delete);

    connect(ui->m_pbuttonSquare,&QPushButton::clicked,this,&SCcalculator::ButtonSquare);
    connect(ui->m_pbutton10PowX,&QPushButton::clicked,this,&SCcalculator::Button10PowX);
    connect(ui->m_pbuttonAbs,&QPushButton::clicked,this,&SCcalculator::ButtonAbs);
    connect(ui->m_pbuttonExp,&QPushButton::clicked,this,&SCcalculator::ButtonExp);

    //音乐播放
    player = new QMediaPlayer();
    playlist = new QMediaPlaylist();
    // 添加音频文件到播放列表
    playlist->addMedia(QUrl::fromLocalFile("D:/CppHomework/MagicCalculator/source/amagi.mp3"));
    // 设置播放模式为循环播放
    playlist->setPlaybackMode(QMediaPlaylist::Loop);
    // 将播放列表设置给播放器
    player->setPlaylist(playlist);
    // 布尔变量用于跟踪音频的播放状态
    bool isPlaying = false;

    QLabel* labelGif = ui->labelGif; // 确保已正确设置对象名称并链接到 UI
    QMovie* movie = new QMovie(":/cxk.gif");
    labelGif->setMovie(movie);
    movie->start();
    labelGif->hide();  // 初始状态隐藏

    connect(ui->m_magic, &QPushButton::clicked, [this, &isPlaying]() {
        if (!isPlaying) {
            // 播放音频
            player->play();
            ui->labelGif->show();  // 显示动图
            isPlaying = true;
        } else {
            // 暂停音频
            player->pause();
            ui->labelGif->hide();  // 隐藏动图
            isPlaying = false;
        }
    });

}

SCcalculator::~SCcalculator()
{
    delete ui;
}

void SCcalculator::button_0(){
    text+="0";
    ui->m_in->setText(QString::fromStdString(text));
    if(calcu.size()>0){
        bool pr=0;
        for(size_t i=0;i<calcu[calcu.size()-1].size();i++){
            char a=calcu[calcu.size()-1][i];
            if(!((a>='0'&&a<='9')||a=='.'))pr=1;
        }
        if(pr==0)calcu[calcu.size()-1]+='0';
        else calcu.push_back("0");
    }
    else calcu.push_back("0");
}

void SCcalculator::button_1(){
    text+="1";
    ui->m_in->setText(QString::fromStdString(text));
    if(calcu.size()>0){
        bool pr=0;
        for(size_t i=0;i<calcu[calcu.size()-1].size();i++){
            char a=calcu[calcu.size()-1][i];
            if(!((a>='0'&&a<='9')||a=='.'))pr=1;
        }
        if(pr==0)calcu[calcu.size()-1]+='1';
        else calcu.push_back("1");
    }
    else calcu.push_back("1");
}

void SCcalculator::button_2(){
    text+="2";
    ui->m_in->setText(QString::fromStdString(text));
    if(calcu.size()>0){
        bool pr=0;
        for(size_t i=0;i<calcu[calcu.size()-1].size();i++){
            char a=calcu[calcu.size()-1][i];
            if(!((a>='0'&&a<='9')||a=='.'))pr=1;
        }
        if(pr==0)calcu[calcu.size()-1]+='2';
        else calcu.push_back("2");
    }
    else calcu.push_back("2");
}

void SCcalculator::button_3(){
    text+="3";
    ui->m_in->setText(QString::fromStdString(text));
    if(calcu.size()>0){
        bool pr=0;
        for(size_t i=0;i<calcu[calcu.size()-1].size();i++){
            char a=calcu[calcu.size()-1][i];
            if(!((a>='0'&&a<='9')||a=='.'))pr=1;
        }
        if(pr==0)calcu[calcu.size()-1]+='3';
        else calcu.push_back("3");
    }
    else calcu.push_back("3");
}

void SCcalculator::button_4(){
    text+="4";
    ui->m_in->setText(QString::fromStdString(text));
    if(calcu.size()>0){
        bool pr=0;
        for(size_t i=0;i<calcu[calcu.size()-1].size();i++){
            char a=calcu[calcu.size()-1][i];
            if(!((a>='0'&&a<='9')||a=='.'))pr=1;
        }
        if(pr==0)calcu[calcu.size()-1]+='4';
        else calcu.push_back("4");
    }
    else calcu.push_back("4");
}

void SCcalculator::button_5(){
    text+="5";
    ui->m_in->setText(QString::fromStdString(text));
    if(calcu.size()>0){
        bool pr=0;
        for(size_t i=0;i<calcu[calcu.size()-1].size();i++){
            char a=calcu[calcu.size()-1][i];
            if(!((a>='0'&&a<='9')||a=='.'))pr=1;
        }
        if(pr==0)calcu[calcu.size()-1]+='5';
        else calcu.push_back("5");
    }
    else calcu.push_back("5");
}

void SCcalculator::button_6(){
    text+="6";
    ui->m_in->setText(QString::fromStdString(text));
    if(calcu.size()>0){
        bool pr=0;
        for(size_t i=0;i<calcu[calcu.size()-1].size();i++){
            char a=calcu[calcu.size()-1][i];
            if(!((a>='0'&&a<='9')||a=='.'))pr=1;
        }
        if(pr==0)calcu[calcu.size()-1]+='6';
        else calcu.push_back("6");
    }
    else calcu.push_back("6");
}

void SCcalculator::button_7(){
    text+="7";
    ui->m_in->setText(QString::fromStdString(text));
    if(calcu.size()>0){
        bool pr=0;
        for(size_t i=0;i<calcu[calcu.size()-1].size();i++){
            char a=calcu[calcu.size()-1][i];
            if(!((a>='0'&&a<='9')||a=='.'))pr=1;
        }
        if(pr==0)calcu[calcu.size()-1]+='7';
        else calcu.push_back("7");
    }
    else calcu.push_back("7");
}

void SCcalculator::button_8(){
    text+="8";
    ui->m_in->setText(QString::fromStdString(text));
    if(calcu.size()>0){
        bool pr=0;
        for(size_t i=0;i<calcu[calcu.size()-1].size();i++){
            char a=calcu[calcu.size()-1][i];
            if(!((a>='0'&&a<='9')||a=='.'))pr=1;
        }
        if(pr==0)calcu[calcu.size()-1]+='8';
        else calcu.push_back("8");
    }
    else calcu.push_back("8");
}

void SCcalculator::button_9(){
    text+="9";
    ui->m_in->setText(QString::fromStdString(text));
    if(calcu.size()>0){
        bool pr=0;
        for(size_t i=0;i<calcu[calcu.size()-1].size();i++){
            char a=calcu[calcu.size()-1][i];
            if(!((a>='0'&&a<='9')||a=='.'))pr=1;
        }
        if(pr==0)calcu[calcu.size()-1]+='9';
        else calcu.push_back("9");
    }
    else calcu.push_back("9");
}

void SCcalculator::button_pi(){
    text+="pi";
    calcu.push_back("pi");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_e(){
    text+="e";
    calcu.push_back("e");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_dot(){
    text+=".";
    ui->m_in->setText(QString::fromStdString(text));
    if(calcu.size()>0){
        bool pr=0;
        for(size_t i=0;i<calcu[calcu.size()-1].size();i++){
            char a=calcu[calcu.size()-1][i];
            if(!((a>='0'&&a<='9')||a=='.'))pr=1;
        }
        if(pr==0)calcu[calcu.size()-1]+='.';
        else calcu.push_back(".");
    }
    else calcu.push_back(".");
}

void SCcalculator::button_plus(){
    text+="+";
    calcu.push_back("+");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_minus(){
    text+="-";
    calcu.push_back("-");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_multiply(){
    text+="*";
    calcu.push_back("*");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_divide(){
    text+="/";
    calcu.push_back("/");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_pow(){
    text+="^";
    calcu.push_back("^");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_mod(){
    text+="%";
    calcu.push_back("%");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_sin(){
    text+="sin(";
    calcu.push_back("sin");
    calcu.push_back("(");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_cos(){
    text+="cos(";
    calcu.push_back("cos");
    calcu.push_back("(");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_tan(){
    text+="tan(";
    calcu.push_back("tan");
    calcu.push_back("(");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_sqrt(){
    text+="sqrt(";
    calcu.push_back("sqrt");
    calcu.push_back("(");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_log(){
    text+="log(";
    calcu.push_back("log");
    calcu.push_back("(");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_ln(){
    text+="ln(";
    calcu.push_back("ln");
    calcu.push_back("(");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_reciprocal(){
    text+="rec(";
    calcu.push_back("rec");
    calcu.push_back("(");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_factorial(){
    text+="fact(";
    calcu.push_back("fact");
    calcu.push_back("(");
    ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_nagative(){
    text+="-";
    calcu.push_back("~");
    ui->m_in->setText(QString::fromStdString(text));
}



void SCcalculator::button_equal(){
    text+="=";
    string b;
    QString c;
    calcu.push_back("=");
    double hist;
    ui->m_in->setText(QString::fromStdString(text));
    try {
       hist=m_cal.doIt(calcu);
       ui->m_out->setText(QString::number(hist));
       history=text;
       history+=c.setNum(hist).toStdString();
    } catch (string a) {
        ui->m_out->setText(QString::fromStdString(a));
        QToolTip::showText(ui->m_in->mapToGlobal(QPoint(100, 0)), "输入格式错误！");
        ui->m_in->setStyleSheet("QLineEdit{border:1px solid red }");
    }
}


void SCcalculator::button_left(){
    text+="(";
    calcu.push_back("(");
    ui->m_in->setText(QString::fromStdString(text));

}

void SCcalculator::button_right(){
    text+=")";
    calcu.push_back(")");
    ui->m_in->setText(QString::fromStdString(text));

}

void SCcalculator::button_clear(){
    ui->m_in->setStyleSheet("QLineEdit{border:1px solid gray border-radius:1px}");
    string s,r;
    r+='0';
    text=s;
    ui->m_in->setText(QString::fromStdString(text));
    ui->m_out->setText(QString::fromStdString(r));
    ui->m_history->setText(QString::fromStdString(history));
    calcu.clear();
}

void SCcalculator::button_clearnum(){
    ui->m_in->setStyleSheet("QLineEdit{border:1px solid gray border-radius:1px}");
    size_t t=0;
    if(calcu.size()>0&&(calcu[calcu.size()-1][0]>='0'&&calcu[calcu.size()-1][0]<='9'||calcu[calcu.size()-1][0] == '.'||calcu[calcu.size()-1][0]=='e'||calcu[calcu.size()-1]=="pi")){
        t=calcu[calcu.size()-1].size();
        calcu.pop_back();
    }
    for(size_t i=0;i<t;i++){
        text.pop_back();
    }
          ui->m_in->setText(QString::fromStdString(text));
}

void SCcalculator::button_delete(){
    ui->m_in->setStyleSheet("QLineEdit{border:1px solid gray border-radius:1px}");
    string s;
    if(text.size()>0){
        if(calcu[calcu.size()-1]=="pi"||calcu[calcu.size()-1]=="sin"||calcu[calcu.size()-1]=="cos"||calcu[calcu.size()-1]=="tan"||calcu[calcu.size()-1]=="sqrt"||calcu[calcu.size()-1]=="fact"||calcu[calcu.size()-1]=="rec"||calcu[calcu.size()-1]=="log"||calcu[calcu.size()-1]=="ln"){
            for(size_t i=0;i<text.size()-calcu[calcu.size()-1].size();i++){
                s+=text[i];
            }
        }
        else{
            for(size_t i=0;i<text.size()-1;i++){
                s+=text[i];
            }
        }
        text=s;
        ui->m_in->setText(QString::fromStdString(text));
        if(calcu[calcu.size()-1].size()>1){
            if(calcu[calcu.size()-1]=="pi"||calcu[calcu.size()-1]=="sin"||calcu[calcu.size()-1]=="cos"||calcu[calcu.size()-1]=="tan"||calcu[calcu.size()-1]=="sqrt"||calcu[calcu.size()-1]=="fact"||calcu[calcu.size()-1]=="rec"||calcu[calcu.size()-1]=="log"||calcu[calcu.size()-1]=="ln")calcu.pop_back();
            else calcu[calcu.size()-1].pop_back();
        }
        else {
            calcu.pop_back();
        }
    }
}

void SCcalculator::ButtonSquare()
{
    QString qstrTextSrc;
    QString qstrTextDst;
    qstrTextSrc = ui->m_in->text();
    double dResult = qstrTextSrc.toDouble();
    dResult = dResult * dResult;
    QTextStream(&qstrTextDst) << dResult;
    ui->m_out->setText(qstrTextDst);
}

void SCcalculator::Button10PowX()
{
    QString qstrTextSrc;
    QString qstrTextDst;
    qstrTextSrc = ui->m_in->text();
    double dResult = qstrTextSrc.toDouble();
    dResult = pow(10, dResult);
    QTextStream(&qstrTextDst) << dResult;
    ui->m_out->setText(qstrTextDst);
}

void SCcalculator::ButtonAbs()
{
    QString qstrTextSrc;
    QString qstrTextDst;
    qstrTextSrc = ui->m_in->text();
    double dResult = qstrTextSrc.toDouble();
    dResult = abs(dResult);
    QTextStream(&qstrTextDst) << dResult;
    ui->m_out->setText(qstrTextDst);
}

void SCcalculator::ButtonExp()
{
    QString qstrTextSrc;
    QString qstrTextDst;
    qstrTextSrc = ui->m_in->text();
    double dResult = qstrTextSrc.toDouble();
    dResult = exp(dResult);
    QTextStream(&qstrTextDst) << dResult;
    ui->m_out->setText(qstrTextDst);
}
